package com.grm.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.grm.entity.User;
import com.grm.service.UserService;

/**
 * desc: 并发处理list的业务实现类
 *
 * @author gaorimao
 * @since 2021-3-14
 */
@Service
public class UserServiceImpl implements UserService {
	private static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
	// 处理的用户数量
	private static final long USER_COUNT = 10000;

	/**
	 * desc: 并发处理list任务，不需要返回值
	 *
	 */
	@Override
	public void sendMessagetoUsers() {
		List<User> users = createUsers();

		// 1.创建线程池
		ExecutorService threadPool = new ThreadPoolExecutor(10, 20, 1, TimeUnit.DAYS, new LinkedBlockingQueue<>());

		for (User user : users) {
			// execute方法，无返回值
			threadPool.execute(sendMessage(user.getId()));
		}

		// 关闭线程池
		threadPool.shutdownNow();
	}

	/**
	 * desc: 并发处理list任务，需要返回值
	 */
	@Override
	public List<String> queryDatas() {
		List<User> users = createUsers();
		
		// 1.创建线程池
		ExecutorService threadPool = new ThreadPoolExecutor(20, Integer.MAX_VALUE, 1, TimeUnit.DAYS,new LinkedBlockingQueue<Runnable>());

		// 2.设置结果集，如果不需要返回值时，不需要此结果
		List<String> results = new ArrayList<>();
		List<Future<String>> futures = new ArrayList<Future<String>>();

		for (User user : users) {
			// execute方法，无返回值
			threadPool.execute(sendMessage(user.getId()));

			// execute方法，无返回值
			Future<String> future = threadPool.submit(queryDataBases("查询数据库", user.getId()));
			futures.add(future);
		}

		// 3.遍历结果集，放在results中，返回给controller
		for (Future<String> future : futures) {
			String result = "";
			try {
				result = future.get();
				results.add(result);
			} catch (InterruptedException e) {
				logger.error("[UserServiceImpl] queryBrands interruptedException = {}", e);
			} catch (ExecutionException e) {
				logger.error("[UserServiceImpl] queryBrands executionException = {}", e);
			}
		}

		// 关闭线程池
		threadPool.shutdownNow();
		return results;
	}

	/**
	 * desc:发消息,不带返回值的操作
	 */
	private Runnable sendMessage(long userId) {
		return new Runnable() {
			@Override
			public void run() {
				logger.info("[UserServiceImpl] sendMessage begin,userId = {}", userId);
			}
		};
	}

	/**
	 * desc: 查询数据库等操作，带返回值的操作
	 *
	 * @author gaorimao
	 * @since 2021-3-15
	 */
	private Callable<String> queryDataBases(String message, long userId) {
		return new Callable<String>() {
			@Override
			public String call() {
				// 一般是查询数据库结果集
				return userId + "=" + message;
			}
		};
	}

	/**
	 * desc: 模拟用户
	 */
	private List<User> createUsers() {
		List<User> users = new ArrayList<>();
		for (int i = 0; i < USER_COUNT; i++) {
			User user = new User(i + 1, "username" + (i + 1));
			users.add(user);
		}
		return users;
	}
}
